#include "NetCDFWriter.h"
#include <string.h>
NetCDFWriter::NetCDFWriter() {}
void NetCDFWriter::open(const std::string &filename)
{
    // 创建NetCDF文件（覆盖模式）
    m_status = nc_create(filename.c_str(), NC_NETCDF4 | NC_CLOBBER, &m_ncid);
    
    // 检查文件是否创建成功
    if (m_status != NC_NOERR) {
        m_ncid = -1;  // 保持无效状态
        // 在控制台打印典型错误码说明提示
        if (m_status == NC_EPERM) {
            std::cerr << "> ERROR: NC_EPERM: Operation not permitted." << std::endl;
            system("pause");
            return;
        }
        if (m_status == NC_ENOMEM) {
            std::cerr << "> ERROR: NC_ENOMEM: Insufficient memory." << std::endl;
            system("pause");
            return;
        }
        if (m_status == NC_ENFILE) {
            std::cerr << "> ERROR: NC_ENFILE: Too many open files." << std::endl;
            system("pause");
            return;
        }
    }
    std::cout << "> NetCDF file created successfully." << std::endl;
}

void NetCDFWriter::close() {
    if (m_ncid != -1) {
        m_status = nc_close(m_ncid);  // 关闭文件
        if (m_status == NC_NOERR) {
            m_ncid = -1;  // 重置文件标识
            std::cout << "> NCFile closed successfully." << std::endl;
        }
    }
}
void NetCDFWriter::addDimension(const std::string &name, size_t length) {
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::addDimension>" << std::endl;
        return;
    }
    
    int dimid;
    m_status = nc_def_dim(m_ncid, name.c_str(), length, &dimid);
    
    if (m_status == NC_NOERR) {
        m_dimIds[name] = dimid;  // 记录维度ID
        std::cout << "> Dimension '" << name << "' added." << std::endl;
    }
}
void NetCDFWriter::addVariable(const std::string &varname, nc_type type, const std::vector<std::string> &dim_names)
{
    // 检查文件状态是否正常
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::addVariable>" << std::endl;
        return;
    }
    
    // 转换维度名称到维度ID
    std::vector<int> dimids;
    for (const auto& dim : dim_names) {
        // 验证维度是否已定义
        if (m_dimIds.count(dim) == 0) {
            m_status = NC_EBADDIM;  // 设置维度不存在错误码 (NC_EBADDIM=-46)
        }
        dimids.push_back(m_dimIds[dim]);  // 获取已注册维度ID
    }

    int varid;
    // 调用NetCDF库函数定义变量
    // 参数说明：
    // m_ncid - 文件ID
    // varname - 变量名称
    // type - 变量数据类型 (如NC_FLOAT)
    // dimids.size() - 维度数量
    // dimids.data() - 维度ID数组指针
    // &varid - 输出变量ID
    m_status = nc_def_var(  m_ncid, 
                            varname.c_str(), 
                            type, 
                            dimids.size(), 
                            dimids.data(), 
                            &varid);
    
    if (m_status == NC_NOERR) {
        m_varIds[varname] = varid;  // 存储变量ID供后续数据写入使用
        std::cout << "> Variable '" << varname << "' defined." << std::endl;
    }
}
void NetCDFWriter::addGlobalAttribute(const std::string &name, double value)
{
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::addGlobalAttribute>" << std::endl;
        return;
    }
    
    // 写入双精度全局属性
    m_status = nc_put_att_double(m_ncid, NC_GLOBAL, name.c_str(),
                                NC_DOUBLE, 1, &value);
    
    // 打印操作结果
    if (m_status == NC_NOERR) {
        std::cout << "> Global attribute '" << name << "' (double) added." << std::endl;
    } else {
        std::cerr << "> ERROR: Failed to add double attribute '" << name << "' (code:" << m_status << ")" << std::endl;
    }
}
void NetCDFWriter::addGlobalAttribute(const std::string &name, float value)
{
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::addGlobalAttribute>" << std::endl;
        return;
    }
    
    // 写入double全局属性
    m_status = nc_put_att_float(m_ncid, NC_GLOBAL, name.c_str(),
                                NC_FLOAT, 1, &value);
    
    // 打印操作结果
    if (m_status == NC_NOERR) {
        std::cout << "> Global attribute '" << name << "' (float) added." << std::endl;
    } else {
        std::cerr << "> ERROR: Failed to add float attribute '" << name << "' (code:" << m_status << ")" << std::endl;
    }
}
void NetCDFWriter::addGlobalAttribute(const std::string &name, int value)
{
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::addGlobalAttribute>" << std::endl;
        return;
    }
    
    // 写入int全局属性
    m_status = nc_put_att_int(m_ncid, NC_INT, name.c_str(),
                                NC_FLOAT, 1, &value);
    
    // 打印操作结果
    if (m_status == NC_NOERR) {
        std::cout << "> Global attribute '" << name << "' (int) added." << std::endl;
    } else {
        std::cerr << "> ERROR: Failed to add int attribute '" << name << "' (code:" << m_status << ")" << std::endl;
    }
}
void NetCDFWriter::addGlobalAttribute(const std::string &name, const std::string &value)
{
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::addGlobalAttribute>" << std::endl;
        return;
    }
    
    // 写入string全局属性
    m_status = nc_put_att_text(m_ncid, NC_GLOBAL, name.c_str(),
                              value.size(), value.c_str());
    
    // 打印操作结果
    if (m_status == NC_NOERR) {
        std::cout << "> Global attribute '" << name 
                  << "' (string) added." << std::endl;
    } else {
        std::cerr << "> ERROR: Failed to add string attribute '" 
                  << name << "' (code:" << m_status << ")" << std::endl;
    }
}
void NetCDFWriter::writeVariableData(const std::string &varname, const std::vector<double> &data)
{
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::writeVariableData>" << std::endl;
        return;
    }
    
    // 验证变量是否已定义
    if (m_varIds.count(varname) == 0) {
        m_status = NC_ENOTVAR;  // 变量不存在错误码
        std::cerr << "> ERROR: Variable '" << varname << "' not defined" << std::endl;
        return;
    }

    // 写入double数据
    m_status = nc_put_var_double(m_ncid, m_varIds[varname], data.data());
    
    if (m_status == NC_NOERR) {
        std::cout << "> Data written to variable '" << varname << "'" << std::endl;
    }
    else {
        std::cerr << "> ERROR: Failed to write data to variable '" << varname << "' (code:" << m_status << ")" << std::endl; 
    }
}
void NetCDFWriter::writeVariableData(const std::string &varname, const std::vector<float> &data)
{
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::writeVariableData>" << std::endl;
        return;
    }
    
    // 验证变量是否已定义
    if (m_varIds.count(varname) == 0) {
        m_status = NC_ENOTVAR;  // 变量不存在错误码
        std::cerr << "> ERROR: Variable '" << varname << "' not defined" << std::endl;
        return;
    }

    // 写入float数据
    m_status = nc_put_var_float(m_ncid, m_varIds[varname], data.data());
    
    if (m_status == NC_NOERR) {
        std::cout << "> Data written to variable '" << varname << "'" << std::endl;
    }
    else {
        std::cerr << "> ERROR: Failed to write data to variable '" << varname << "' (code:" << m_status << ")" << std::endl; 
    }
}
void NetCDFWriter::writeVariableData(const std::string &varname, const std::vector<int> &data)
{
    if (m_status != NC_NOERR){
        std::cerr << "> ERROR: NetCDF file is not open. <NetCDFReader::writeVariableData>" << std::endl;
        return;
    }
    
    // 验证变量是否已定义
    if (m_varIds.count(varname) == 0) {
        m_status = NC_ENOTVAR;  // 变量不存在错误码
        std::cerr << "> ERROR: Variable '" << varname << "' not defined" << std::endl;
        return;
    }

    // 写入int数据
    m_status = nc_put_var_int(m_ncid, m_varIds[varname], data.data());
    
    if (m_status == NC_NOERR) {
        std::cout << "> Data written to variable '" << varname << "'" << std::endl;
    }
    else {
        std::cerr << "> ERROR: Failed to write data to variable '" << varname << "' (code:" << m_status << ")" << std::endl; 
    }
}
/*void NetCDFReader::writeVariableData(const std::string &varname, const std::vector<std::string> &data)
{
    if (m_status != NC_NOERR) return;
    
    // 验证变量是否已定义
    if (m_varIds.count(varname) == 0) {
        m_status = NC_ENOTVAR;
        std::cerr << "> ERROR: Variable '" << varname << "' not defined" << std::endl;
        return;
    }

    // 计算最大字符串长度
    size_t max_len = 0;
    for (const auto& str : data) {
        max_len = std::max(max_len, str.size());
    }

    // 创建二维字符数组缓冲区
    std::vector<char> buffer(data.size() * max_len, ' ');
    for (size_t i = 0; i < data.size(); ++i) {
        const std::string& str = data[i];
        // 安全写法：限制拷贝长度不超过缓冲区空间
        size_t copy_len = std::min(str.size(), max_len);
        strncpy(&buffer[i * max_len], str.c_str(), copy_len);
        
        // 显式填充剩余空间（原实现已用空格初始化缓冲区）
        if (copy_len < max_len) {
            memset(&buffer[i * max_len + copy_len], ' ', max_len - copy_len);
        }
    }

    // 写入文本数据
    m_status = nc_put_var_text(m_ncid, m_varIds[varname], buffer.data());
    
    if (m_status == NC_NOERR) {
        std::cout << "> String data written to variable '" << varname << "'" << std::endl;
    } else {
        std::cerr << "> ERROR: Failed to write string data (code:" << m_status << ")" << std::endl;
    }
}*/
NetCDFWriter::~NetCDFWriter() {}